#include<iostream>
#include<unistd.h>
#include<signal.h>
#include<vector>


#define MAXSIGN 31

std::vector<int> BLOCKARR = {2,3};

static void sigPrintf(const sigset_t * pending)
{
    // 因为2号信号集在最左边，所以我们要从31号信号开始打印
    for(int i = MAXSIGN ; i >= 1 ; i--)
    {
        if(  sigismember(pending,i) )
        {
            std::cout << "1";
        } 
        else 
        {
            std::cout << "0";
        }
    }
    // 最后输出换行，刷新缓冲区

    std::cout<<std::endl;
}

void handler(int signo)
{
    std::cout << "捕捉到一个信号，信号编号是：" << signo << std::endl;
}

int main()
{
    // 为了能更好的看清楚实验现象，我们对要处理的信号进程捕捉
    for(const auto&signo : BLOCKARR) signal(signo,handler);
 
    sigset_t block,oblock,pending;
    // 先初始化 sigset_t 系列函数
    sigemptyset(&block);
    sigemptyset(&oblock);
    //用户层次上设置阻塞集
    for(const auto& sig : BLOCKARR) sigaddset(&block,sig);

    //系统层次上设置阻塞集
    sigprocmask(SIG_BLOCK,&block,&oblock);


    // 获取未决信号，看看实验现象
    int cnt = 10; // 我决定10秒后解除阻塞
    while(true)
    {
        // 初始化，获取pending信号集
        sigemptyset(&pending);
        sigpending(&pending);
        sigPrintf(&pending);

        sleep(1);
        if(cnt-- == 0 )
        {


            std::cout << "解开阻塞，信号立即递达" << std::endl;
            sigprocmask(SIG_SETMASK,&oblock,&block);

            // 要在后续ctrl+c继续被阻塞，那就在递达后立刻阻塞上
            //std::cout << "请注意5s后，信号会重新堵塞，届时信号不会被递达" << std::endl;
           //sleep(5);
        
            sigprocmask(SIG_SETMASK,&block,&oblock);
        }

    }


    return 0;
}

